import { sound,filters} from "@pixi/sound";
import { ResourceLoader } from "@/utils/ResourceLoader.js";
export class SeStaticAudio{
    constructor(parent){
        this.parent=parent;
        this._volume=1;
        this._speed=1;
        this.soundsMap=new Map();
        this.filter=null;

        this.loadtaskCount=0;

        this.loadCbs=[];
    }

    clear(){
        this.soundsMap.clear();
    }

    get mastervolume(){
        return this.parent?.volume??1;
    }

    set volume(value){
        this._volume=value;
        let resultVolume=value*this.mastervolume;
        this.soundsMap.forEach((value)=>{
            value.volume=resultVolume;
        });
    }

    get volume(){
        return this._volume??1;
    }

    set pan(value){
        if(!this.filter){
            if(value==0)return;
            this.filter=new filters.StereoFilter(value);
            this.soundsMap.forEach((value)=>{
                value.filters=[this.filter];
            },this);
        }else{
            this.filter.pan=value;
        }
    }
    get pan(){
        return this.filter?.pan??0;
    }

    play(name){
        if(!name)return;
        let soundObject=this.soundsMap.get(name);
        if(!soundObject){
            this._load(name);
        }else{
            if(typeof soundObject == 'boolean'){
                this.loadPush('play',name);
                return;
            }
            soundObject.play(this.makePlayOptions());
        }
    }
    load(name){
        if(!name)return;
        if(!this.soundsMap.has(name)){
            this._load(name,this._preonload);
        }
    }

    _load(name,loaded){
        let url=`/audio/se/${name}.ogg`;
        ++this.loadtaskCount;
        this.soundsMap.set(name,true);
        if(window.$dataSystem?.hasEncryptedAudio){
            ResourceLoader.loadEncrypterSound(url).then(source=>{
                sound.add(`${name}_se`,this.makeOptions({
                    source,
                    name,
                    ...(loaded&&{loaded})
                }));
            });
        }else{
            sound.add(`${name}_se`,this.makeOptions({
                url,
                name,
                ...(loaded&&{loaded})
            }));
        }
    }

    stop(){
        this.soundsMap.forEach((value)=>{
            value.stop();
        })
    }

    isReady(){
        return this.loadtaskCount<=0;
    }

    loadPush(method,...args){
        this.loadCbs.push({method,args});
    }

    loadCompleteCall(){
        let cbs=this.loadCbs;
        this.loadCbs=[];
        for(let cb of cbs){
            this[cb.method]?.(...cb.args);
        }
    }

    _onload=(err,soundObject)=>{
        soundObject.play(this.makePlayOptions());
        this.soundsMap.set(soundObject.options.name,soundObject);
        --this.loadtaskCount;
        this.loadCompleteCall();
    }

    _preonload=(err,soundObject)=>{
        this.soundsMap.set(soundObject.options.name,soundObject);
        --this.loadtaskCount;
        this.loadCompleteCall();
    }

    makeOptions(opts){
        return {
            preload:true,
            loaded:this._onload,
            ...opts
        };
    }

    makePlayOptions(opts){
        let options={
            volume:this.volume*this.mastervolume,
            speed:this._speed,
            ...opts
        };

        if(this.filter){
            options.filters=[this.filter];
        }
        return options;
    }
}